package com.plian.system.service.sys.warning.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.plian.Tools.CollectionUtil;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.config.exception.MyRuntimeException;
import com.plian.system.constant.sys.WarningConfigConstant;
import com.plian.system.dao.sys.fun.PerGroupDao;
import com.plian.system.dao.sys.per.PerUserDao;
import com.plian.system.dto.sys.warning.WarningMessageConfigDTO;
import com.plian.system.entity.sys.User;
import com.plian.system.entity.sys.UserOrg;
import com.plian.system.entity.sys.warning.*;
import com.plian.system.mapper.sys.warning.WarningMessageConfigMapper;
import com.plian.system.model.ObjResult;
import com.plian.system.mybatis.support.Condition;
import com.plian.system.service.sys.user.ISysUserService;
import com.plian.system.service.sys.user.IUserOrgService;
import com.plian.system.service.sys.warning.*;
import com.plian.system.vo.sys.warning.WarningMessageConfigRoleRelationVO;
import com.plian.system.vo.sys.warning.WarningMessageConfigVO;
import com.plian.system.vo.sys.warning.WarningMessageLightConfigVO;
import com.plian.system.vo.sys.warning.WarningMessageRuleConfigVO;
import com.plian.system.wrapper.sys.warning.*;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@AllArgsConstructor
public class WarningMessageConfigServiceImpl extends ServiceImpl<WarningMessageConfigMapper, WarningMessageConfig> implements IWarningMessageConfigService {

    private IWarningMessageConfigUserRelationService warningMessageConfigUserRelationService;

    private IWarningMessageConfigRoleRelationService warningMessageConfigRoleRelationService;

    private IWarningMessageRuleConfigService warningMessageRuleConfigService;

    private IWarningMessageLightConfigService warningMessageLightConfigService;

    private WarningMessageConfigWrapper warningMessageConfigWrapper;

    private WarningMessageConfigRoleRelationWrapper warningMessageConfigRoleRelationWrapper;

    private WarningMessageConfigUserRelationWrapper warningMessageConfigUserRelationWrapper;

    private WarningMessageRuleConfigWrapper warningMessageRuleConfigWrapper;

    private WarningMessageLightConfigWrapper warningMessageLightConfigWrapper;

    private PerGroupDao perGroupDao;

    private PerUserDao perUserDao;

    private ISysUserService sysUserService;

    private IUserOrgService userOrgService;

//    private IWarningFactorService warningFactorService; TODO DEL

    @Override
    public WarningMessageConfigVO detail(WarningMessageConfig warningMessageConfig) {
        WarningMessageConfigVO warningMessageConfigVO = warningMessageConfigWrapper.entityToVO(getOne(Condition.getQueryWrapper(warningMessageConfig)));
        warningMessageConfigVO.setRoleRelationVOS(warningMessageConfigRoleRelationWrapper
                .entityToVO(warningMessageConfigRoleRelationService.list(Wrappers.<WarningMessageConfigRoleRelation>lambdaQuery()
                        .eq(WarningMessageConfigRoleRelation::getConfigId, warningMessageConfigVO.getId()))));
        if (CollectionUtil.isNotEmpty(warningMessageConfigVO.getRoleRelationVOS())){
            try {
                Map<String, PageData> roleMap = perGroupDao.listAll().stream().collect(Collectors.toMap(role -> role.getString("id"), a -> a, (k1, k2) -> k1));
                for (WarningMessageConfigRoleRelationVO warningMessageConfigRoleRelationVO : warningMessageConfigVO.getRoleRelationVOS()){
                    if (roleMap.containsKey(warningMessageConfigRoleRelationVO.getRoleId())){
                        warningMessageConfigRoleRelationVO.setRoleName(roleMap.get(warningMessageConfigRoleRelationVO.getRoleId()).getString("name"));
                    }
                }
            }catch (Exception e){
                log.error("获取角色信息失败", e);
            }
        }
        warningMessageConfigVO.setUserRelationVOS(warningMessageConfigUserRelationWrapper
                .entityToVO(warningMessageConfigUserRelationService.list(Wrappers.<WarningMessageConfigUserRelation>lambdaQuery()
                        .eq(WarningMessageConfigUserRelation::getConfigId, warningMessageConfigVO.getId()))));
        List<WarningMessageLightConfigVO> warningMessageLightConfigVOS = warningMessageLightConfigWrapper
                .entityToVO(warningMessageLightConfigService.list(Wrappers.<WarningMessageLightConfig>lambdaQuery()
                .eq(WarningMessageLightConfig::getConfigId, warningMessageConfigVO.getId())));
        warningMessageConfigVO.setLightConfigVOS(warningMessageLightConfigVOS);
        if (CollectionUtil.isNotEmpty(warningMessageLightConfigVOS)){
            for (WarningMessageLightConfigVO warningMessageLightConfigVO : warningMessageLightConfigVOS){
                List<WarningMessageRuleConfigVO> warningMessageRuleConfigVOS = warningMessageRuleConfigWrapper.entityToVO(warningMessageRuleConfigService.list(Wrappers.<WarningMessageRuleConfig>lambdaQuery()
                        .eq(WarningMessageRuleConfig::getLightConfigId, warningMessageLightConfigVO.getId())));
                if (CollectionUtil.isNotEmpty(warningMessageRuleConfigVOS)){
                    Map<Long, WarningMessageRuleConfigVO> ruleConfigIdMap = warningMessageRuleConfigVOS.stream().collect(Collectors.toMap(WarningMessageRuleConfig::getId, ruleConfigVO -> ruleConfigVO));
                    for (WarningMessageRuleConfigVO ruleConfigVO : warningMessageRuleConfigVOS){
                        if(ruleConfigVO.getIsRoot() == 1){
                            warningMessageLightConfigVO.setRuleConfigVO(ruleConfigVO);
                        }
                        if (ruleConfigVO.getLinkId() != null && ruleConfigIdMap.containsKey(ruleConfigVO.getLinkId())){
                            WarningMessageRuleConfigVO configVO = ruleConfigIdMap.get(ruleConfigVO.getLinkId());
                            if (ruleConfigVO.getLinkType() == WarningConfigConstant.VERTICAL_LINK_TYPE){
                                configVO.setVerticalVO(ruleConfigVO);
                            }else if (ruleConfigVO.getLinkType() == WarningConfigConstant.TRANSVERSE_LINK_TYPE){
                                configVO.setTransverseVO(ruleConfigVO);
                            }
                        }
                    }
                }
            }
        }


        return warningMessageConfigVO;
    }

    @Override
    public boolean submit(WarningMessageConfigVO warningMessageConfigVO) {
        WarningMessageConfig warningMessageConfig = warningMessageConfigWrapper.voToEntity(warningMessageConfigVO);
        int sendType = 0;
        //task 发送类型 0不发送 1启动task 2停止task
        if (warningMessageConfig.getId() == null){
            sendType = 1;
        }else {
            WarningMessageConfig oldConfig = getById(warningMessageConfig.getId());
            if (!warningMessageConfig.getIsEffective().equals(oldConfig.getIsEffective())){
                if (warningMessageConfig.getIsEffective() == 1){
                    sendType = 1;
                }else {
                    sendType = 2;
                }
            }
        }

        boolean flag = saveOrUpdate(warningMessageConfig);

        List<WarningMessageConfigUserRelation> userRelationList = warningMessageConfigUserRelationWrapper.voToEntity(warningMessageConfigVO.getUserRelationVOS());
        warningMessageConfigUserRelationService.remove(Wrappers.<WarningMessageConfigUserRelation>lambdaQuery().eq(WarningMessageConfigUserRelation::getConfigId, warningMessageConfig.getId()));
        if (CollectionUtil.isNotEmpty(userRelationList)){
            for (WarningMessageConfigUserRelation userRelation : userRelationList){
                userRelation.setConfigId(warningMessageConfig.getId());
            }
            warningMessageConfigUserRelationService.saveBatch(userRelationList);
        }

        List<WarningMessageConfigRoleRelation> roleRelationList = warningMessageConfigRoleRelationWrapper.voToEntity(warningMessageConfigVO.getRoleRelationVOS());
        warningMessageConfigRoleRelationService.remove(Wrappers.<WarningMessageConfigRoleRelation>lambdaQuery().eq(WarningMessageConfigRoleRelation::getConfigId, warningMessageConfig.getId()));
        if (CollectionUtil.isNotEmpty(roleRelationList)){
            for (WarningMessageConfigRoleRelation roleRelation : roleRelationList){
                roleRelation.setConfigId(warningMessageConfig.getId());
            }
            warningMessageConfigRoleRelationService.saveBatch(roleRelationList);
        }

        warningMessageLightConfigService.remove(Wrappers.<WarningMessageLightConfig>lambdaQuery().eq(WarningMessageLightConfig::getConfigId, warningMessageConfig.getId()));
        warningMessageRuleConfigService.remove(Wrappers.<WarningMessageRuleConfig>lambdaQuery().eq(WarningMessageRuleConfig::getConfigId, warningMessageConfig.getId()));
//        if (CollectionUtil.isNotEmpty(warningMessageConfigVO.getLightConfigVOS())){
//            Map<Long, WarningFactor> factorMap = warningFactorService.list().stream().collect(Collectors.toMap(WarningFactor::getId, warningFactor -> warningFactor));
//            for (WarningMessageLightConfigVO lightConfigVO : warningMessageConfigVO.getLightConfigVOS()){
//                WarningMessageLightConfig lightConfig = warningMessageLightConfigWrapper.voToEntity(lightConfigVO);
//                lightConfig.setConfigId(warningMessageConfig.getId());
//                String formula = rootRuleConfigVOToFormula(lightConfigVO.getRuleConfigVO(), factorMap);
//                lightConfig.setFormula(formula);
//                warningMessageLightConfigService.saveOrUpdate(lightConfig);
//                saveRuleConfig(lightConfigVO.getRuleConfigVO(), lightConfig.getId(), warningMessageConfig.getId(), 1, 0L, 0);
//            }
//        }
//        if (sendType == 1){
//            warningTaskClient.start(warningMessageConfig.getId());
//        }else if (sendType == 2){
//            warningTaskClient.start(warningMessageConfig.getId());
//        }
        return flag;
    }

    private void saveRuleConfig(WarningMessageRuleConfigVO ruleConfigVO, Long  lightConfigId, Long configId, int isRoot, Long linkId, int linkType){
        if (ruleConfigVO != null){
            WarningMessageRuleConfig ruleConfig = warningMessageRuleConfigWrapper.voToEntity(ruleConfigVO);
            ruleConfig.setLightConfigId(lightConfigId);
            ruleConfig.setConfigId(configId);
            ruleConfig.setLinkType(linkType);
            ruleConfig.setIsRoot(isRoot);
            ruleConfig.setLinkId(linkId);
            warningMessageRuleConfigService.save(ruleConfig);
            saveRuleConfig(ruleConfigVO.getVerticalVO(), lightConfigId, configId, 0, ruleConfig.getId(), WarningConfigConstant.VERTICAL_LINK_TYPE);
            saveRuleConfig(ruleConfigVO.getTransverseVO(), lightConfigId, configId, 0, ruleConfig.getId(), WarningConfigConstant.TRANSVERSE_LINK_TYPE);
        }
    }

//    private String rootRuleConfigVOToFormula(WarningMessageRuleConfigVO ruleConfigVO, Map<Long, WarningFactor> factorMap){ TODO DEL
//        HashMap<Integer, String> levelFormulaMap = new HashMap<>();
//        HashMap<Integer, Integer> levelRelationMap = new HashMap<>();
//        setLevelFormulaMap(ruleConfigVO, ROOT_TYPE, 1, levelFormulaMap, levelRelationMap, factorMap);
//        String formula = "";
//        if (CollectionUtil.isNotEmpty(levelFormulaMap)){
//            for (Integer level : levelFormulaMap.keySet()){
//                if (level == 1){
//                    formula = "(" + levelFormulaMap.get(level) + ")";
//                    continue;
//                }
//                int ruleRelation = levelRelationMap.get(level);
//                if (formula.length() == 0){
//                    formula = "(" + levelFormulaMap.get(level) + ")";
//                }else {
//                    formula = formula + (ruleRelation == 1 ? " && " : " || ") + "(" + levelFormulaMap.get(level) + ")";
//                }
//            }
//        }
//        return formula;
//    }

//    /**
//     *TODO DEL
//     * @param ruleConfigVO
//     * @param type  0root 1vertical 2transverse
//     * @param level
//     * @param levelFormulaMap
//     */
//    private void setLevelFormulaMap(WarningMessageRuleConfigVO ruleConfigVO, int type, int level, Map<Integer, String> levelFormulaMap, Map<Integer, Integer> levelRelationMap, Map<Long, WarningFactor> factorMap) {
//        if (type == ROOT_TYPE){
//            levelFormulaMap.put(level, ruleConfigToFormula(ruleConfigVO, factorMap));
//            if (ruleConfigVO.getVerticalVO() != null){
//                setLevelFormulaMap(ruleConfigVO.getVerticalVO(), VERTICAL_LINK_TYPE, level + 1, levelFormulaMap, levelRelationMap, factorMap);
//            }
//            if (ruleConfigVO.getTransverseVO() != null){
//                setLevelFormulaMap(ruleConfigVO.getTransverseVO(), TRANSVERSE_LINK_TYPE, level, levelFormulaMap, levelRelationMap, factorMap);
//            }
//        }else if (type == VERTICAL_LINK_TYPE){
//            levelFormulaMap.put(level, ruleConfigToFormula(ruleConfigVO, factorMap));
//            levelRelationMap.put(level, ruleConfigVO.getRuleRelation());
//            if (ruleConfigVO.getVerticalVO() != null){
//                setLevelFormulaMap(ruleConfigVO.getVerticalVO(), VERTICAL_LINK_TYPE, level + 1, levelFormulaMap, levelRelationMap, factorMap);
//            }
//            if (ruleConfigVO.getTransverseVO() != null){
//                setLevelFormulaMap(ruleConfigVO.getTransverseVO(), TRANSVERSE_LINK_TYPE, level, levelFormulaMap, levelRelationMap, factorMap);
//            }
//        }else if (type == TRANSVERSE_LINK_TYPE){
//            String formula = levelFormulaMap.get(level) + (ruleConfigVO.getRuleRelation() == 1 ? " && " : " || ") + ruleConfigToFormula(ruleConfigVO, factorMap);
//            levelFormulaMap.put(level, formula);
//            if (ruleConfigVO.getTransverseVO() != null){
//                setLevelFormulaMap(ruleConfigVO.getTransverseVO(), TRANSVERSE_LINK_TYPE, level, levelFormulaMap, levelRelationMap, factorMap);
//            }
//        }
//    }

//    private String ruleConfigToFormula(WarningMessageRuleConfigVO ruleConfigVO, Map<Long, WarningFactor> factorMap){ TODO DEL
//        if (StrUtil.isNotBlank(ruleConfigVO.getThresholdRange())
//                && ruleConfigVO.getTargetFactorId() != null && ruleConfigVO.getTargetFactorId() != 0L
//                && factorMap.containsKey(ruleConfigVO.getFactorId())
//                && factorMap.containsKey(ruleConfigVO.getTargetFactorId())){
//            WarningFactor factor = factorMap.get(ruleConfigVO.getFactorId());
//            WarningFactor targetFactor = factorMap.get(ruleConfigVO.getTargetFactorId());
//            return  factor.getFactorCode() + " " + ruleConfigVO.getConditionRule() + " " + ruleConfigVO.getThresholdRange()
//                    + " || " + factor.getFactorCode() + " " + ruleConfigVO.getConditionRule() + " " + targetFactor.getFactorCode();
//        }
//
//        if (StrUtil.isNotBlank(ruleConfigVO.getThresholdRange())
//                && (ruleConfigVO.getTargetFactorId() == null || ruleConfigVO.getTargetFactorId() == 0L)
//                && factorMap.containsKey(ruleConfigVO.getFactorId())){
//            return factorMap.get(ruleConfigVO.getFactorId()).getFactorCode() + " " + ruleConfigVO.getConditionRule() + " " + ruleConfigVO.getThresholdRange();
//        }
//
//        if (StrUtil.isBlank(ruleConfigVO.getThresholdRange())
//                && ruleConfigVO.getTargetFactorId() != null && ruleConfigVO.getTargetFactorId() != 0L
//                && factorMap.containsKey(ruleConfigVO.getFactorId())
//                && factorMap.containsKey(ruleConfigVO.getTargetFactorId())){
//            return factorMap.get(ruleConfigVO.getFactorId()).getFactorCode() + " " + ruleConfigVO.getConditionRule() + " " + factorMap.get(ruleConfigVO.getTargetFactorId()).getFactorCode();
//        }
//        return "";
//    }

    @Override
    public boolean removeAndChild(WarningMessageConfigDTO warningMessageConfigDTO) {
        warningMessageConfigUserRelationService.remove(Wrappers.<WarningMessageConfigUserRelation>lambdaQuery()
                .in(WarningMessageConfigUserRelation::getConfigId, warningMessageConfigDTO.getIds()));
        warningMessageConfigRoleRelationService.remove(Wrappers.<WarningMessageConfigRoleRelation>lambdaQuery()
                .in(WarningMessageConfigRoleRelation::getConfigId, warningMessageConfigDTO.getIds()));
        warningMessageLightConfigService.remove(Wrappers.<WarningMessageLightConfig>lambdaQuery()
                .in(WarningMessageLightConfig::getConfigId, warningMessageConfigDTO.getIds()));
        warningMessageRuleConfigService.remove(Wrappers.<WarningMessageRuleConfig>lambdaQuery()
                .in(WarningMessageRuleConfig::getConfigId, warningMessageConfigDTO.getIds()));
        return removeByIds(warningMessageConfigDTO.getIds());
    }

    @Override
    public boolean enable(Long id) {
        WarningMessageConfig messageConfig = getById(id);
        if (messageConfig == null){
            throw new MyRuntimeException(new ObjResult("未找到该预警消息配置"));
        }
        messageConfig.setIsEffective(1);
//        warningTaskClient.start(id);
        return saveOrUpdate(messageConfig);
    }

    @Override
    public boolean stop(Long id) {
        WarningMessageConfig messageConfig = getById(id);
        if (messageConfig == null){
            throw new MyRuntimeException(new ObjResult("未找到该预警消息配置"));
        }
        messageConfig.setIsEffective(0);
//        warningTaskClient.stop(id);
        return saveOrUpdate(messageConfig);
    }

    @Override
    public List<User> getAllUserById(Long id, String orgId) {
        List<User> userList = new ArrayList<>();
        List<WarningMessageConfigUserRelation> userRelations = warningMessageConfigUserRelationService.list(Wrappers.<WarningMessageConfigUserRelation>lambdaQuery()
                .eq(WarningMessageConfigUserRelation::getConfigId, id));
        if (CollectionUtil.isNotEmpty(userRelations)){
            List<String> userIds = userOrgService.list(Wrappers.<UserOrg>lambdaQuery().eq(UserOrg::getOrgId, orgId))
                    .stream().map(UserOrg::getUserId).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(userIds)) {
                List<WarningMessageConfigUserRelation> tempUserIds = userRelations.stream()
                        .filter(userRelation -> userIds.contains(userRelation.getUserId())).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(tempUserIds)) {
                    userList.addAll(sysUserService.listByIds(tempUserIds));
                }
            }
        }
        List<WarningMessageConfigRoleRelation> roleRelations = warningMessageConfigRoleRelationService.list(Wrappers.<WarningMessageConfigRoleRelation>lambdaQuery()
                .eq(WarningMessageConfigRoleRelation::getConfigId, id));
        if (CollectionUtil.isNotEmpty(roleRelations)){
            PageData roleQuery = new PageData();
            roleQuery.put("roleIds", roleRelations.stream().map(WarningMessageConfigRoleRelation::getRoleId).collect(Collectors.toList()));
            roleQuery.put("orgIds", Stream.of(orgId).collect(Collectors.toList()));
            try {
                List<PageData> perUsers = perUserDao.getUsers(roleQuery);
                if (CollectionUtil.isNotEmpty(perUsers)){
                    for (PageData perUser : perUsers){
                        User user = new User();
                        user.setId(perUser.getString("id"));
                        user.setName(perUser.getString("name"));
                        user.setUsername(perUser.getString("username"));
                        user.setPhone(perUser.getString("phone"));
                        userList.add(user);
                    }
                }
            }catch (Exception e){
                log.error("获取角色下的用户失败", e);
            }
        }
        return userList;
    }
}
